/*
 * Created by JFormDesigner on Mon Aug 16 15:39:21 CST 2021
 */

package com.minelx.tableui.form;

import com.intellij.uiDesigner.core.*;
import com.minelx.landisk.filesystem.Paths;
import com.minelx.landisk.filesystem.core.Directory;
import com.minelx.landisk.filesystem.core.File;
import com.minelx.table.core.Table;
import com.minelx.table.core.Tables;
import com.minelx.tableui.common.Chooser;
import com.minelx.tableui.model.TableColumnsListModel;

import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;

import static com.minelx.tableui.common.Chooser.chooseCharset;
import static javax.swing.JOptionPane.showMessageDialog;

/**
 * @author aaa
 */
public class PreviewForm extends JFrame {

	static {
		try {
			UIManager.setLookAndFeel(new NimbusLookAndFeel());
		} catch (UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}
	}

	private TableColumnsListModel columnsListModel;

	private final Directory workingDir;

	public static void main(String[] args) {
		new PreviewForm(Tables.csv("a,b\n" +
				"1,2\n" +
				"1,3\n" +
				"2,4\n" +
				"2,"), Paths.projectRoot()).setVisible(true);
	}

	public PreviewForm(Table table, Directory workingDir) {
		initComponents();

		// do init
		bindModel(table);
		this.workingDir = workingDir;
	}

	private void bindModel(Table table) {
		columnsListModel = new TableColumnsListModel(table);
		columnsList.setModel(columnsListModel);
	}

	private void openFileMenuButtonActionPerformed(ActionEvent e) {
		File csvFile = Chooser.openFile(this, workingDir);
		try {
			bindModel(Tables.csv(csvFile.read(chooseCharset())));
		} catch (IOException exception) {
			exception.printStackTrace();
		}
	}

	private void saveFileMenuButtonActionPerformed(ActionEvent e) {
		Table table = columnsListModel.getTable();
		try {
			Chooser.saveFile(this, workingDir)
					.write(table.toText(), StandardCharsets.UTF_8);
			showMessageDialog(this, "done saving.");
		} catch (IOException exception) {
			exception.printStackTrace();
		}
	}

	private void deleteColumnButtonActionPerformed(ActionEvent e) {
		columnsListModel.remove(columnsList.getSelectedIndex());
	}

	private void moveColumnUpButtonActionPerformed(ActionEvent e) {
		int selectedIndex = getSelectedIndex();
		columnsListModel.swap(selectedIndex, throwIfOutOfRange(selectedIndex - 1));
	}

	private void moveColumnDownButtonActionPerformed(ActionEvent e) {
		int selectedIndex = getSelectedIndex();
		columnsListModel.swap(selectedIndex, throwIfOutOfRange(selectedIndex + 1));
	}

	private void innerJoinButtonActionPerformed(ActionEvent e) {
		int selectedIndex = getSelectedIndex();
		File joinedFile = Chooser.openFile(this, workingDir);
		try {
			Table joinedTable = Tables.csv(joinedFile.read(chooseCharset()));
			columnsListModel.innerJoin(
					joinedTable,
					columnsListModel.getElementAt(selectedIndex));
		} catch (IOException exception) {
			exception.printStackTrace();
		}
	}

	private void convertToText(ActionEvent e) {
		columnsListModel.mapColumn(getSelectedIndex(), value -> value + "\t");
	}

	private void filterNaN(ActionEvent e) {
		columnsListModel.filterRows(getSelectedIndex(), value -> !value.isEmpty());
	}

	private int throwIfOutOfRange(int destinationIndex) {
		if (destinationIndex < 0 || destinationIndex >= columnsListModel.getSize()) {
			throw new IllegalArgumentException("destination index out of range.");
		}
		return destinationIndex;
	}

	private int getSelectedIndex() {
		int result = columnsList.getSelectedIndex();
		if (result == -1) {
			throw new IllegalStateException("no column selected.");
		}
		return result;
	}

	private void initComponents() {
		// JFormDesigner - Component initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
		menuBar1 = new JMenuBar();
		menu1 = new JMenu();
		openFileMenuButton = new JMenuItem();
		saveFileMenuButton = new JMenuItem();
		panel1 = new JPanel();
		label1 = new JLabel();
		panel5 = new JPanel();
		panel3 = new JPanel();
		label2 = new JLabel();
		panel4 = new JPanel();
		deleteColumnButton = new JButton();
		moveColumnUpButton = new JButton();
		moveColumnDownButton = new JButton();
		innerJoinButton = new JButton();
		panel2 = new JPanel();
		convertToTextButton = new JButton();
		filterNaNButton = new JButton();
		scrollPane1 = new JScrollPane();
		columnsList = new JList<>();

		//======== this ========
		setTitle("\u5217\u6a21\u5f0f");
		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		Container contentPane = getContentPane();
		contentPane.setLayout(new BorderLayout());

		//======== menuBar1 ========
		{

			//======== menu1 ========
			{
				menu1.setText("\u6587\u4ef6");
				menu1.setFont(new Font("Microsoft JhengHei UI Light", Font.PLAIN, 20));

				//---- openFileMenuButton ----
				openFileMenuButton.setText("\u6253\u5f00");
				openFileMenuButton.setFont(new Font("Microsoft JhengHei UI Light", Font.PLAIN, 20));
				openFileMenuButton.addActionListener(e -> openFileMenuButtonActionPerformed(e));
				menu1.add(openFileMenuButton);

				//---- saveFileMenuButton ----
				saveFileMenuButton.setText("\u4fdd\u5b58");
				saveFileMenuButton.setFont(new Font("Microsoft JhengHei UI Light", Font.PLAIN, 20));
				saveFileMenuButton.addActionListener(e -> saveFileMenuButtonActionPerformed(e));
				menu1.add(saveFileMenuButton);
			}
			menuBar1.add(menu1);
		}
		setJMenuBar(menuBar1);

		//======== panel1 ========
		{
			panel1.setBorder(new EmptyBorder(12, 12, 12, 12));
			panel1.setLayout(new BorderLayout(20, 0));

			//---- label1 ----
			label1.setText("\u5217\u9884\u89c8");
			label1.setFont(new Font("Microsoft JhengHei UI Light", Font.PLAIN, 20));
			panel1.add(label1, BorderLayout.NORTH);

			//======== panel5 ========
			{
				panel5.setLayout(new BorderLayout());

				//======== panel3 ========
				{
					panel3.setLayout(new GridLayoutManager(3, 1, new Insets(0, 0, 0, 0), 0, 0));

					//---- label2 ----
					label2.setFont(new Font("Microsoft JhengHei UI Light", Font.PLAIN, 20));
					label2.setText("\u5bf9\u5217\u8fdb\u884c\u64cd\u4f5c:");
					panel3.add(label2, new GridConstraints(0, 0, 1, 1,
						GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
						GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
						GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
						null, null, null));

					//======== panel4 ========
					{
						panel4.setLayout(new FlowLayout(FlowLayout.LEFT));

						//---- deleteColumnButton ----
						deleteColumnButton.setText("\u5220\u9664\u5217");
						deleteColumnButton.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 12));
						deleteColumnButton.addActionListener(e -> deleteColumnButtonActionPerformed(e));
						panel4.add(deleteColumnButton);

						//---- moveColumnUpButton ----
						moveColumnUpButton.setText("\u2191");
						moveColumnUpButton.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 12));
						moveColumnUpButton.addActionListener(e -> moveColumnUpButtonActionPerformed(e));
						panel4.add(moveColumnUpButton);

						//---- moveColumnDownButton ----
						moveColumnDownButton.setText("\u2193");
						moveColumnDownButton.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 12));
						moveColumnDownButton.addActionListener(e -> moveColumnDownButtonActionPerformed(e));
						panel4.add(moveColumnDownButton);

						//---- innerJoinButton ----
						innerJoinButton.setText("\u5185\u8fde\u63a5");
						innerJoinButton.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 12));
						innerJoinButton.addActionListener(e -> innerJoinButtonActionPerformed(e));
						panel4.add(innerJoinButton);
					}
					panel3.add(panel4, new GridConstraints(1, 0, 1, 1,
						GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE,
						GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
						GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
						null, null, null));

					//======== panel2 ========
					{
						panel2.setLayout(new FlowLayout());

						//---- convertToTextButton ----
						convertToTextButton.setText("\u8f6c\u6362\u4e3a\u6587\u672c");
						convertToTextButton.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 12));
						convertToTextButton.addActionListener(e -> convertToText(e));
						panel2.add(convertToTextButton);

						//---- filterNaNButton ----
						filterNaNButton.setText("\u8fc7\u6ee4\u7a7a\u503c");
						filterNaNButton.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 12));
						filterNaNButton.addActionListener(e -> filterNaN(e));
						panel2.add(filterNaNButton);
					}
					panel3.add(panel2, new GridConstraints(2, 0, 1, 1,
						GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL,
						GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
						GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
						null, null, null));
				}
				panel5.add(panel3, BorderLayout.NORTH);
			}
			panel1.add(panel5, BorderLayout.EAST);

			//======== scrollPane1 ========
			{

				//---- columnsList ----
				columnsList.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 22));
				scrollPane1.setViewportView(columnsList);
			}
			panel1.add(scrollPane1, BorderLayout.CENTER);
		}
		contentPane.add(panel1, BorderLayout.CENTER);
		setSize(925, 715);
		setLocationRelativeTo(getOwner());
		// JFormDesigner - End of component initialization  //GEN-END:initComponents
	}

	// JFormDesigner - Variables declaration - DO NOT MODIFY  //GEN-BEGIN:variables
	private JMenuBar menuBar1;
	private JMenu menu1;
	private JMenuItem openFileMenuButton;
	private JMenuItem saveFileMenuButton;
	private JPanel panel1;
	private JLabel label1;
	private JPanel panel5;
	private JPanel panel3;
	private JLabel label2;
	private JPanel panel4;
	private JButton deleteColumnButton;
	private JButton moveColumnUpButton;
	private JButton moveColumnDownButton;
	private JButton innerJoinButton;
	private JPanel panel2;
	private JButton convertToTextButton;
	private JButton filterNaNButton;
	private JScrollPane scrollPane1;
	private JList<String> columnsList;
	// JFormDesigner - End of variables declaration  //GEN-END:variables
}
